home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Libraries / MacWT 0.04 / turlsLibs / FixMulDiv.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-31  |  2.0 KB  |  118 lines  |  [TEXT/MMCC]

  1. #include "UseAsm.h"
  2. #ifndef    __TOOLUTILS__
  3. #include <ToolUtils.h>
  4. #include <FixMath.h>
  5. #endif
  6.  
  7.  
  8. #if __MWERKS__
  9. #       pragma require_prototypes off
  10. #elif THINK_C || THINK_CPLUS
  11. #       pragma options(!require_protos)
  12. #endif
  13.  
  14.  
  15. /**/
  16.  
  17.  
  18. #if USE_ASM
  19.  
  20.  
  21. ASM_FUNC long mc68k_fixmul(/*long a, long b*/)
  22. {
  23.   ASM_BEGIN
  24.     //-------------------------
  25.     //
  26.     // Routine       : m68k_fixmul -- 16:16 fixed-point multiply
  27.     // Registers used: d0-d2
  28.     // REQUIRES A 68020
  29.     //
  30.  
  31.     //-------------------------
  32.     //
  33.     // Pickup parameters...
  34.     //
  35.     move.l    4(A7), d0
  36.     move.l    8(A7), d1
  37.     dc.w    0x4c01, 0x0c01    // muls.l d1, d1:d0
  38.     move.w    d1, d0
  39.     swap    d0
  40.   ASM_END
  41. }
  42.  
  43.  
  44. // Quickie -- use FracMul instead of rolling my own...
  45. ASM_FUNC long mc68k_fixmul2_30(/*long a, long b*/)
  46. {
  47.     // return FracMul(a, b);
  48.     // requires 68020!
  49.  
  50.   ASM_BEGIN
  51.  
  52.     move.l    4(A7), d0
  53.     move.l    8(A7), d1
  54.     dc.w    0x4c01, 0x0c01    // muls.l d1, d1:d0
  55.  
  56.     // we could probably just do a "move.l d1, d0" here
  57.     // and lose the lower 2 bits, but...
  58.  
  59.     lsl.l    #2, d1            // shift 'em back up;
  60.     rol.l    #2, d0            // shift top 2 bits of D0 down to bottom
  61.     and.l    #3, d0            // clear out all other bits
  62.     or.l    d1, d0            // or in the "real" result!
  63.  
  64.   ASM_END
  65. }
  66.  
  67.  
  68. ASM_FUNC long mc68k_fixdiv(/*long num, long denom*/)
  69. {
  70.   ASM_BEGIN
  71.     //-------------------------
  72.     //
  73.     // Routine       : mc68k_fixdiv -- 16:16 fixed-point divide
  74.     // Registers used: d0-d2
  75.     // REQUIRES A 68020
  76.     //
  77.  
  78.     move.l    4(A7), d2        // numerator
  79.     move.l    8(A7), d1        // denominator
  80.     beq.s    @bad            // divide by zero -- oops!
  81.  
  82.     move.w    d2, d0            // split d2 between d2 and d0
  83.     swap    d0
  84.     clr.w    d0
  85.     swap    d2
  86.     ext.l    d2
  87.     dc.w    0x4C41, 0x0C02    // divs.l    d1, d2:d0
  88.     bra.s    @end
  89. @bad:
  90.     moveq    #-2, d0
  91.     ror.l    #1, d0            // sneakily get 0x7FFFFFFF into D0.L
  92.     tst.l    d2
  93.     bgt.s    @end            // if numerator > 0, return 0x7FFFFFFF
  94.     neg.l    d0                // return 0x80000001
  95. @end:
  96.  
  97.   ASM_END
  98. }
  99.  
  100. #else    /* USE_ASM */
  101.  
  102. long mc68k_fixmul(long a, long b)
  103. {
  104.     return FixMul(a, b);
  105. }
  106.  
  107. long mc68k_fixmul2_30(long a, long b)
  108. {
  109.     return FracMul(a, b);
  110. }
  111.  
  112. long mc68k_fixdiv(long num, long denom)
  113. {
  114.     return FixDiv(num, denom);
  115. }
  116.  
  117. #endif    /* USE_ASM */
  118.